package com.baitiaojun.video.service.impl;

import com.baitiaojun.api.domain.video.VideoLike;
import com.baitiaojun.api.domain.video.VideoOperation;
import com.baitiaojun.api.exception.ConditionException;
import com.baitiaojun.api.util.ConstantUtil;
import com.baitiaojun.api.util.SnowFlakeUtil;
import com.baitiaojun.api.vo.LikeCoinOperatedCollectedInfo;
import com.baitiaojun.video.mapper.VideoLikeMapper;
import com.baitiaojun.video.mapper.VideoMapper;
import com.baitiaojun.video.mapper.VideoOperationMapper;
import com.baitiaojun.video.service.VideoLikeService;
import com.baitiaojun.video.support.RedisSupport;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @类名 VideoLikeServiceImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/2/23 16:37
 * @版本 1.0
 */
@Service
public class VideoLikeServiceImpl implements VideoLikeService {

    @Resource
    private VideoMapper videoMapper;

    @Resource
    private VideoLikeMapper videoLikeMapper;

    @Resource
    private VideoOperationMapper videoOperationMapper;

    @Autowired
    private RedisSupport redisSupport;

    @Transactional
    @Override
    public void addVideoLike(Long videoId, Long userId) throws ConditionException {
        Integer isExists = videoMapper.isExistsVideo(videoId);
        if (ObjectUtils.isEmpty(isExists)) {
            throw new ConditionException("不存在此视频");
        }
        Integer isLike = videoLikeMapper.isLike(videoId, userId);
        if (ObjectUtils.isNotEmpty(isLike)) {
            throw new ConditionException("该视频已被点赞");
        }
        //用户不能给自己点赞
        Long uId = videoMapper.selectUserIdByVideoId(videoId);
        if (userId.equals(uId)) {
            throw new ConditionException("点赞失败，up主不能给自己点赞~");
        }
        //如果该视频存在且没有被点赞就进行videolilke添加
        int resVideoLike = videoLikeMapper.insertSelective(VideoLike.builder()
                .id(SnowFlakeUtil.getNextId())
                .videoId(videoId)
                .userid(userId)
                .createtime(new Date())
                .build());
        if (resVideoLike == 0) {
            throw new ConditionException("添加用户点赞失败");
        }
        VideoOperation videoOperation = new VideoOperation();
        videoOperation.setId(SnowFlakeUtil.getNextId());
        videoOperation.setUserid(userId);
        videoOperation.setVideoid(videoId);
        videoOperation.setCreatetime(new Date());
        videoOperation.setOperationtype("0");
        int resVideoOperation = videoOperationMapper.insertSelective(videoOperation);
        if (resVideoOperation == 0) {
            throw new ConditionException("添加视频点赞操作记录失败");
        }
    }

    @Transactional
    @Override
    public void cancelVideoLike(Long videoId, Long userId) throws ConditionException {
        int resVideoLike = videoLikeMapper.deleteVideoLike(videoId, userId);
        if (resVideoLike == 0) {
            throw new ConditionException("用户取消点赞失败");
        }
        VideoOperation videoOperation = new VideoOperation();
        videoOperation.setUserid(userId);
        videoOperation.setVideoid(videoId);
        videoOperation.setOperationtype(ConstantUtil.OPERATION_TYPE_LIKE);
        int resVideoOperation = videoOperationMapper.deleteVideoOperation(videoOperation);
        if (resVideoOperation == 0) {
            throw new ConditionException("取消视频点赞操作记录失败");
        }
    }

    @Override
    public LikeCoinOperatedCollectedInfo getVideoLike(Long userId, Long videoId) {
        int count = videoLikeMapper.selectVideoLikeCount(videoId);
        Integer isLike = videoLikeMapper.isLike(videoId, userId);
        return LikeCoinOperatedCollectedInfo.builder().count(count).flag("like", ObjectUtils.isNotEmpty(isLike)).build();
    }

    @Override
    public Integer getVideoLikeCount(Long videoId) {
        Object likeCount = redisSupport.getValue(ConstantUtil.LIKE_COUNT + videoId);
        if (ObjectUtils.isEmpty(likeCount)) {
            synchronized (this) {
                likeCount = redisSupport.getValue(ConstantUtil.LIKE_COUNT + videoId);
                if (ObjectUtils.isEmpty(likeCount)) {
                    Integer count = videoLikeMapper.selectVideoLikeCount(videoId);
                    redisSupport.setValue(ConstantUtil.LIKE_COUNT + videoId, count, 1, TimeUnit.DAYS);
                    return count;
                }
            }
        }
        return videoLikeMapper.selectVideoLikeCount(videoId);
    }
}
